from knowledge.manager import KnowledgeManager
from knowledge.retriever import KnowledgeRetriever
from knowledge.segmenter import KnowledgeSegmenter
from utils.commont_util import md5_encrypt


class Know():

    def __init__(self,know_name):
        # 初始化模块
        self.segmenter = KnowledgeSegmenter()
        self.retriever = KnowledgeRetriever()
        self.manager = KnowledgeManager(know_name)

    def add_img_know(self,img_base64):
        # 图片算出hash然后作为id直接保存 暂时保留 未实现
        pass
    def add_knows(self,long_text):
        texts = self.segmenter.seg(long_text)
        for txt in texts:
            self.manager.add_knowledge(txt)
        return texts

    def get_all_know(self):
        return self.manager.get_all_know()


    def get_know_txt(self,know_id):
        return self.manager.get_knowledge(know_id)

    def get_know_id(self,know_text):
        return md5_encrypt(know_text,True)

    def query(self,question,top_k=10):
        know_texts = self.get_all_know()
        query_texts = self.retriever.retrieve(question,know_texts,top_k)
        return query_texts

    def remove_know(self,know_name):
#         删除知识库 预留
        pass


if __name__ == '__main__':
    # 新建一个知识库
    know =Know("测试知识库")
    long_text ="""
    在自然语言处理（NLP）中，文本分块是一个至关重要的步骤，它旨在将长文本分解成更小、更易于处理的部分。这些小块通常基于单词的词性和语法结构进行划分，例如名词短语、动词短语等。通过文本分块，我们可以更高效地从文本中提取关键信息，提高语言理解和信息提取的准确性和效率。

文本分块的重要性

在处理大型语言模型（如RAG）时，文本分块的重要性不容忽视。这是因为一次性提取整个文档的嵌入向量可能会导致信息丢失或产生不准确的结果。正确的文本分块策略可以确保每个小块都包含有足够的信息，同时避免在提取关键信息时丢失重要内容。

文本分块策略

在自然语言处理中，有多种文本分块策略可供选择。每种策略都有其独特的优点和适用场景。以下是一些常见的文本分块策略：

传统方法拆分
简单粗暴方式（正则拆分）
优点：简单易行，适用于结构较为规整的文本。
缺点：对于复杂或格式不规范的文本，正则表达式可能无法准确地进行分块。
适用场景：适用于结构较为规整的文本，如新闻、博客等。

基于规则的拆分
基于规则的拆分通常依赖于一组预定义的规则，这些规则根据语法结构、词性等信息对文本进行拆分。
优点：规则可定制化，适用于特定领域的文本处理任务。
缺点：需要手动定义规则集，且对于复杂的语法结构可能难以覆盖全面。
适用场景：适用于特定领域的文本处理任务，如法律、医学等。

基于机器学习的拆分
基于机器学习的拆分利用训练数据来学习文本分块的规则和模式。常见的算法包括条件随机场（CRF）和深度学习模型。
优点：能够自动学习分块规则，提高准确性。
缺点：需要大量的训练数据，且模型训练时间较长。
适用场景：适用于大规模的文本处理任务，如社交媒体、新闻等。

基于深度学习的拆分
基于深度学习的拆分利用深度学习模型（如LSTM、BERT等）对文本进行编码，然后根据编码结果进行拆分。
优点：能够捕获文本中的复杂模式和上下文信息，准确性较高。
缺点：需要大量的计算资源和训练时间。
适用场景：适用于需要高准确性的大型文本处理任务，如文献挖掘、专利分析等。

如何找到适合你项目的文本分块策略

在选择适合你项目的文本分块策略时，需要考虑以下几个因素：

任务需求：首先明确你的项目需求是什么，是进行信息抽取、问答系统还是情感分析等。不同的任务需求可能需要不同的分块策略。
数据规模和多样性：如果你的项目处理的数据规模较大或者具有多种不同形式，基于深度学习的分块策略可能更适合你。而对于特定领域的文本处理任务，基于规则的拆分可能更有优势。
计算资源和时间限制：评估你的计算资源和时间限制也是重要的一步。基于深度学习的分块策略通常需要更多的计算资源和训练时间，而简单的正则表达式或基于规则的分块方法可能更适合时间有限的情况。
团队技能和经验：最后，还要考虑团队对不同分块策略的技能和经验。如果你有强大的机器学习团队，基于深度学习的分块策略可能更适合你的项目。反之，如果团队更熟悉正则表达式或规则集，那么基于简单正则表达式或基于规则的分块方法可能更合适。
实验和验证：在选择一个具体的分块策略后，一定要进行实验和验证以评估其效果。可以通过比较不同策略在相同数据集上的表现来选择最佳的分块方法。同时也要注意评估指标的选择，确保它们能够真实反映你的项目需求和目标。
    """
    # 添加知识库
    res = know.add_knows(long_text)
    # 查询知识库
    texts = know.query("文本分块是一个至关重要的步骤")
    print(texts)
